package com.eleadin.ruleengine.easyrules;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eleadin.ruleengine.easyrules.rules.AgeRule;
import com.eleadin.ruleengine.easyrules.rules.WeatherRule;
import com.eleadin.ruleengine.easyrules.utils.EasyRulesUtil;
import com.eleadin.ruleengine.easyrules.vo.StudentVO;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.core.DefaultRulesEngine;

public class RuleEngineDemo {

    public static void testAgeRule() {
        AgeRule ageRule = new AgeRule();
        Rules rules = new Rules();
        rules.register(ageRule);
        DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
        Facts facts = new Facts();
        facts.put("age", 20);
        rulesEngine.fire(rules, facts);
    }

    public static void testWeatherRule() {
        WeatherRule weatherRule = new WeatherRule();
        Rules rules = new Rules();
        rules.register(weatherRule);
        DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
        Facts facts = new Facts();
        facts.put("rain", true);
        rulesEngine.fire(rules, facts);
    }

    /**
     * 规则，要求英语成绩小于等于90，且 数学成绩小于80， 则认为匹配
     * 非json对象，可以通过   user.score.englishScore 的方式进行级联访问某个子属性值
     *            也可以通过 user.getScore().getEnglishScore() 的方式进行级联访问某个子属性值
     * json对象，级联访问目前没有通过，需要更换访问方案
     */
    public static void testAndOperationRule() {
        // 1. 新增规则
        EasyRulesUtil.RuleModel ruleModel = new EasyRulesUtil.RuleModel();
        ruleModel.setRuleId("2");
        ruleModel.setRuleName("rule2");
        ruleModel.setDescription("测试and规则");
        // 2. 设置规则条件
        String ruleJson = "{\n" +
                "    \"validateCondition\": {\n" +
                "        \"type\": \"RELATION\",\n" +
                "        \"operator\": \"AND\",\n" +
                "        \"children\": [\n" +
                "            {\n" +
                "                \"type\": \"EXPRESSION\",\n" +
                "                \"operator\": \"LESS_THAN\",\n" +
                "                \"metricName\": \"score.englishScore\",\n" +
                "                \"value\": \"90\",\n" +
                "                \"children\": []\n" +
                "            },\n" +
                "            {\n" +
                "                \"type\": \"EXPRESSION\",\n" +
                "                \"operator\": \"LESS_THAN_EQUAL\",\n" +
                "                \"metricName\": \"getScore().getMathScore()\",\n" +
                "                \"value\": \"80\",\n" +
                "                \"children\": []\n" +
                "            }\n" +
                "        ]\n" +
                "    }\n" +
                "}\n";
        JSONObject conditionJson = JSON.parseObject(ruleJson);
        // 3. 设置fact
        EasyRulesUtil easyRulesUtil = new EasyRulesUtil(false);
        String whenExpression = easyRulesUtil.buildWhenExpression(conditionJson.getJSONObject("validateCondition"));
        System.out.println("whenExpression：" + whenExpression);
        ruleModel.setWhenExpression(whenExpression);
        // 4. 设置结果表达式
        ruleModel.setThenExpression(EasyRulesUtil.buildThenExpression());

        // 5. 设置匹配条件
        String scoreStr = "{\n" +
                "  \"name\":\"xiao ming\",\n" +
                "  \"score\":{\"englishScore\":80,\"mathScore\":80}\n" +
                "}";
        StudentVO studentVO = JSON.parseObject(scoreStr, StudentVO.class);


        // 6. 调用规则匹配
        EasyRulesUtil.RuleResult result = easyRulesUtil.matchObject(studentVO, ruleModel);
        System.out.println(result);
    }

    public static void testMVELOperationRule() {

        // 1. 新增规则
        EasyRulesUtil.RuleModel ruleModel = new EasyRulesUtil.RuleModel();
        ruleModel.setRuleId("1");
        ruleModel.setRuleName("rule1");
        ruleModel.setDescription("测试规则");
        // 2. 设置规则条件
        String ruleJson = "{\n" +
                "    \"validateCondition\": {\n" +
                "        \"type\": \"RELATION\",\n" +
                "        \"operator\": \"OR\",\n" +
                "        \"children\": [\n" +
                "            {\n" +
                "                \"type\": \"EXPRESSION\",\n" +
                "                \"operator\": \"LESS_THAN\",\n" +
                "                \"metricName\": \"NORMAL_NUMBER\",\n" +
                "                \"value\": \"11\",\n" +
                "                \"children\": []\n" +
                "            },\n" +
                "            {\n" +
                "                \"type\": \"EXPRESSION\",\n" +
                "                \"operator\": \"LESS_THAN_EQUAL\",\n" +
                "                \"metricName\": \"ERROR_NUMBER\",\n" +
                "                \"value\": \"11\",\n" +
                "                \"children\": []\n" +
                "            },\n" +
                "            {\n" +
                "                \"type\": \"RELATION\",\n" +
                "                \"children\": [\n" +
                "                    {\n" +
                "                        \"type\": \"EXPRESSION\",\n" +
                "                        \"metricName\": \"NORMAL_NUMBER\",\n" +
                "                        \"operator\": \"GREATER_THAN\",\n" +
                "                        \"value\": 10,\n" +
                "                        \"children\": []\n" +
                "                    },\n" +
                "                    {\n" +
                "                        \"type\": \"EXPRESSION\",\n" +
                "                        \"metricName\": \"ERROR_NUMBER\",\n" +
                "                        \"operator\": \"GREATER_THAN\",\n" +
                "                        \"value\": 100,\n" +
                "                        \"children\": []\n" +
                "                    },\n" +
                "                    {\n" +
                "                        \"type\": \"RELATION\",\n" +
                "                        \"children\": [\n" +
                "                            {\n" +
                "                                \"type\": \"EXPRESSION\",\n" +
                "                                \"metricName\": \"NORMAL_NUMBER\",\n" +
                "                                \"operator\": \"EQUAL\",\n" +
                "                                \"value\": 1,\n" +
                "                                \"children\": []\n" +
                "                            },\n" +
                "                            {\n" +
                "                                \"type\": \"EXPRESSION\",\n" +
                "                                \"metricName\": \"ERROR_NUMBER\",\n" +
                "                                \"operator\": \"EQUAL\",\n" +
                "                                \"value\": 1,\n" +
                "                                \"children \": []\n" +
                "                            }\n" +
                "                        ],\n" +
                "                        \"operator\": \"OR\"\n" +
                "                    }\n" +
                "                ],\n" +
                "                \"operator\": \"OR\"\n" +
                "            }\n" +
                "        ]\n" +
                "    }\n" +
                "}";
        JSONObject conditionJson = JSON.parseObject(ruleJson);
        // 3. 设置fact
        EasyRulesUtil easyRulesUtil = new EasyRulesUtil(true);
        String whenExpression = easyRulesUtil.buildWhenExpression(conditionJson.getJSONObject("validateCondition"));
        System.out.println("whenExpression：" + whenExpression );
        ruleModel.setWhenExpression(whenExpression);
        // 4. 设置结果表达式
        ruleModel.setThenExpression(EasyRulesUtil.buildThenExpression());

        // 5. 设置匹配条件
        JSONObject json = new JSONObject();
//        json.put("NORMAL_NUMBER", "10");
        json.put("ERROR_NUMBER", 10);
//        json.put("省=陕西；市=西安;", 100);

        // 6. 调用规则匹配
        EasyRulesUtil.RuleResult result = easyRulesUtil.match(json, ruleModel);
        System.out.println(result);

    }

    public static void main(String[] args) {

//        RuleEngineDemo.testAgeRule();
//        RuleEngineDemo.testWeatherRule();
        RuleEngineDemo.testAndOperationRule();;

    }
}
